/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许，不可做商业用途！
 *
 * 版权所有，侵权必究！
 */
package com.yami.shop.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.PhoneUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yami.shop.bean.app.param.UserRegisterParam;
import com.yami.shop.bean.event.UserDataEvent;
import com.yami.shop.bean.event.UserDestroyEvent;
import com.yami.shop.bean.model.*;
import com.yami.shop.bean.param.*;
import com.yami.shop.common.config.Constant;
import com.yami.shop.common.enums.StatusEnum;
import com.yami.shop.common.enums.UserLevelType;
import com.yami.shop.common.exception.YamiShopBindException;
import com.yami.shop.common.i18n.I18nMessage;
import com.yami.shop.common.i18n.LanguageEnum;
import com.yami.shop.common.util.*;
import com.yami.shop.dao.UserMapper;
import com.yami.shop.service.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.poi.ss.usermodel.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotNull;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author lgh on 2018/09/11.
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Value("${yami.expose.operation.auth:}")
    private Boolean permission;

    private final UserMapper userMapper;
    private final UserExtensionService userExtensionService;
    private final UserCollectionService userCollectionService;
    private final UserCollectionShopService userCollectionShopService;
    private final ApplicationEventPublisher eventPublisher;

    @Override
    public User getUserByUserId(String userId) {
        return userMapper.selectById(userId);
    }

    @Override
    public void setUserLevelBylevelId(Integer level, Integer levelType) {
        userMapper.setUserLevelBylevelId(level, levelType);
        userExtensionService.setUserLevelBylevelId(level, levelType);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void setUserLevelByGrowth(Integer level, Integer minNeedGrowth, Integer maxNeedGrowth, Integer levelType) {
        userMapper.setMaxUserLevelBylevelId(level, minNeedGrowth, maxNeedGrowth, levelType);
//        userExtensionService.setMaxUserLevelByLevelId(level, minNeedGrowth, maxNeedGrowth, levelType);
    }


    /**
     * 看看有没有校验验证码成功的标识
     *
     * @param userRegisterParam
     * @param checkRegisterSmsFlag
     */
    @Override
    public void validate(UserRegisterParam userRegisterParam, String checkRegisterSmsFlag) {
        if (StrUtil.isBlank(userRegisterParam.getCheckRegisterSmsFlag())) {
            // 验证码已过期，请重新发送验证码校验
            throw new YamiShopBindException("yami.verification.expire");
        } else {
            String checkRegisterSmsFlagMobile = RedisUtil.get(checkRegisterSmsFlag);
            if (!Objects.equals(checkRegisterSmsFlagMobile, userRegisterParam.getMobile())) {
                // 验证码已过期，请重新发送验证码校验
                throw new YamiShopBindException("yami.verification.expire");
            }
        }
    }

    @Override
    public User getUserDetail(String userId) {
        return userMapper.getUserDetail(userId);
    }

    @Override
    public IPage<User> getUserPage(PageParam<User> page, User user) {
        return userMapper.getUserPage(page, user);
    }

    @Override
    public Map<String, User> getUserListByUserNumbers(Set<String> keySet) {
        if (keySet.size() == 0) {
            return new HashMap<>(16);
        }
        List<User> userList = userMapper.getUserListByUserNumbers(keySet);
        Map<String, User> userMap = userList.stream().collect(Collectors.toMap(User::getUserId, user -> user));
        return userMap;
    }

    @Override
    public CustomerRespParam countUserByParam(CustomerReqParam param) {
        CustomerRespParam respParam = new CustomerRespParam();
        Date endTime = param.getEndTime();
        Date startTime = param.getStartTime();
        // 累积粉丝数
        param.setAppId(1);
        param.setDateTime(endTime);
        if (Objects.isNull(param.getShopId())) {
            param.setMember(1);
            // 累计应该没有时间
            param.setStartTime(null);
            param.setEndTime(null);
            param.setDateTime(null);
            respParam.setFashNum(userMapper.countUserByParam(param));
            param.setDateTime(startTime);
            respParam.setPreFashNum(userMapper.countUserByParam(param));
            respParam.setFashNumRate(divRate(respParam.getPreFashNum(), respParam.getFashNum(), 4));
        }

        // 累积会员数
        param.setDateTime(null);
        param.setMember(null);
        param.setAppId(null);
        param.setDateTime(endTime);
        respParam.setMember(userMapper.countMemberByParam(param));
        param.setDateTime(startTime);
        respParam.setPreMember(userMapper.countMemberByParam(param));
        respParam.setMemberRate(divRate(respParam.getMember() - respParam.getPreMember(), respParam.getMember(), 4));

        return respParam;
    }

    @Override
    public IPage<UserManagerParam> getUserInfoPage(PageParam<User> page, UserManagerReqParam user) {
        // user基本信息 积分 当前余额  累计金额
        Page<UserManagerParam> pages = new Page<>();
        pages.setCurrent(page.getCurrent());
        pages.setSize(page.getSize());
        List<UserManagerParam> list = userMapper.getUserPageByParam(new PageAdapter(page), user);
        for (UserManagerParam userManagerParam : list) {
            //订单实际支付金额/订单没有优惠的金额  不包含积分订单
            userManagerParam.setAverDiscount(divAverage(userManagerParam.getOrderActualAmount(), userManagerParam.getConsAmount(), 2));
            if (BooleanUtil.isFalse(permission)) {
                if (Objects.nonNull(userManagerParam.getUserMobile())) {
                    userManagerParam.setUserMobile(PhoneUtil.hideBetween(userManagerParam.getUserMobile()).toString());
                }
                //昵称符合正则时就**
                if (PrincipalUtil.isMobile(userManagerParam.getNickName())) {
                    userManagerParam.setNickName(PhoneUtil.hideBetween(userManagerParam.getNickName()).toString());
                }
            }
            handleUserNullValue(userManagerParam);
        }
        pages.setRecords(list);
        Integer total = userMapper.countGetUserPageByParam(new PageAdapter(page), user);
        pages.setTotal(total);
        return pages;
    }

    @Override
    public IPage<UserManagerParam> getUserInfoPage(Page<User> page, UserManagerReqParam user) {
        // user基本信息 积分 当前余额  累计金额
        Page<UserManagerParam> pages = new Page<>();
        pages.setSize(page.getSize());
        pages.setCurrent(page.getCurrent());
        List<UserManagerParam> list = userMapper.getUserPageByParam(new PageAdapter(page), user);
        for (UserManagerParam userManagerParam : list) {
            handleUserNullValue(userManagerParam);
        }
        pages.setRecords(list);
        return pages;
    }

    private void handleUserNullValue(UserManagerParam userManagerParam) {
        if (Objects.isNull(userManagerParam.getConsAmount())) {
            userManagerParam.setConsAmount(Constant.ZERO_DOUBLE);
        }
        if (Objects.isNull(userManagerParam.getConsTimes())) {
            userManagerParam.setConsTimes(0);
        }
        if (Objects.isNull(userManagerParam.getReduceAmount())) {
            userManagerParam.setReduceAmount(Constant.ZERO_DOUBLE);
        }
        userManagerParam.setAverDiscount(Arith.div(userManagerParam.getOrderActualAmount(), userManagerParam.getConsAmount(), 2));
        if (Objects.isNull(userManagerParam.getAfterSaleAmount())) {
            userManagerParam.setAfterSaleAmount(Constant.ZERO_DOUBLE);
        }
        if (Objects.isNull(userManagerParam.getAfterSaleTimes())) {
            userManagerParam.setAfterSaleTimes(0);
        }
        if (Objects.isNull(userManagerParam.getSumScore())) {
            userManagerParam.setSumScore(0);
        }
        if (Objects.isNull(userManagerParam.getRechargeAmount())) {
            userManagerParam.setRechargeAmount(Constant.ZERO_DOUBLE);
        }
        if (Objects.isNull(userManagerParam.getRechargeTimes())) {
            userManagerParam.setRechargeTimes(0);
        }
    }

    @Override
    public UserManagerParam getuserInfo(String userId) {
        UserManagerParam param = userMapper.getuserInfo(userId);
        if (BooleanUtil.isFalse(permission) && PrincipalUtil.isMobile(param.getNickName())) {
            param.setNickName(PhoneUtil.hideBetween(param.getNickName()).toString());
        }
        param.setCurrentScore(param.getScore());
        eventPublisher.publishEvent(new UserDataEvent(param));
        return param;
    }

    @Override
    public void downloadUserModel(HttpServletResponse response) {
        // 下载用户导入模板
        downloadUserModelExcel(response);
    }

    @Override
    public UserExcelParam parseUserImportFile(MultipartFile excelFile, List<UserLevelParam> userLevels) throws IOException {
        Integer lang = I18nMessage.getDbLang();
        UserExcelParam resParam = new UserExcelParam();
        resParam.setSuccess(false);
        resParam.setImmediately(false);
        // 普通会员
        List<UserLevelParam> ordinary = userLevels.stream().filter(item -> Objects.equals(0, item.getLevelType())).collect(Collectors.toList());
        // 付费会员
        List<UserLevelParam> pay = userLevels.stream().filter(item -> Objects.equals(1, item.getLevelType())).collect(Collectors.toList());
        try (InputStream inputStream = excelFile.getInputStream();
             Workbook workBook = WorkbookFactory.create(inputStream)) {
            // * 2.1不是Excel文件，直接返回提示信息
            if (!(excelFile.getOriginalFilename().contains(Constant.XLS_FILE) || excelFile.getOriginalFilename().contains(Constant.XLSX_FILE))) {
                // 格式错误
                throw new YamiShopBindException("yami.file.error");
            }
            //读取工作表
            Sheet sheet = workBook.getSheetAt(0);
            int rowNums = sheet.getPhysicalNumberOfRows();
            //校验是否填写内容
            if (rowNums <= 1) {
                // 文件无内容
                throw new YamiShopBindException("yami.document.no.content");
            }
            // 总计导入数据条数
            int total = 0;
            List<UserRegisterExcelParam> userList = new ArrayList<>();
            Set<String> phoneSet = new HashSet<>();
            Set<String> mailSet = new HashSet<>();
            List<String> errorRows = new ArrayList<>();
            long currentTime = LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli();
            //循环读取每一行数据并校验
            for (int i = 1; i < rowNums; i++) {
                total++;
                try {
                    //读取行
                    Row row = sheet.getRow(i);
                    int cell = 0;
                    // 序号
                    String serialNo = PoiExcelUtil.getRowValue(row, cell, false);
                    // 手机号
                    String phone = PoiExcelUtil.getRowValue(row, ++cell, false);
                    // 密码
                    String password = PoiExcelUtil.getRowValue(row, ++cell, false);
                    // 会员类型(0普通会员/1付费会员)，不填默认为普通会员
                    String levelType = PoiExcelUtil.getRowValue(row, ++cell, false);
                    // vip结束时间
                    String vipEndTime = PoiExcelUtil.getRowValue(row, ++cell, false);
                    if (Objects.equals(levelType, UserLevelType.VIP.value().toString())) {
                        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                        LocalDateTime ldt = LocalDateTime.parse(DateUtil.parse(vipEndTime, "yyyy-MM-dd").toString(), dtf);
                        //获取毫秒数
                        long milliSecond = ldt.toInstant(ZoneOffset.of("+8")).toEpochMilli();
                        if (currentTime >= milliSecond) {
                            levelType = UserLevelType.ORDINARY.value().toString();
                        }
                    }
                    // 用户昵称
                    String nickName = PoiExcelUtil.getRowValue(row, ++cell, false);
                    // 邮箱
                    String userMail = PoiExcelUtil.getRowValue(row, ++cell, false);
                    // 性别
                    String sex = PoiExcelUtil.getRowValue(row, ++cell, false);
                    // 生日
                    String birthDate = PoiExcelUtil.getRowValue(row, ++cell, false);
                    // 备注
                    String userMemo = PoiExcelUtil.getRowValue(row, ++cell, false);
                    // 积分
                    String score = PoiExcelUtil.getRowValue(row, ++cell, true);
                    // 余额
                    String balance = PoiExcelUtil.getRowValue(row, ++cell, true);
                    // 成长值
                    String growth = PoiExcelUtil.getRowValue(row, ++cell, true);
                    if (checkData(lang, phoneSet, mailSet, errorRows, i, phone, password, nickName, userMail)){ continue; }
                    phoneSet.add(phone);
                    mailSet.add(userMail);
                    UserRegisterExcelParam param = getUserRegisterExcelParam(lang, ordinary, pay, errorRows, i, serialNo, phone, password, levelType, vipEndTime, nickName, userMail, sex, birthDate, userMemo, score, balance, growth);
                    if (param == null) { continue; }
                    userList.add(param);
                } catch (Exception e) {
                    errorRows.add(Objects.equals(lang, LanguageEnum.LANGUAGE_ZH_CN.getLang()) ?"第"+ (i + 1) + "行" + e.getMessage():"Line " + (i + 1) + e.getMessage());
                    // 错误信息提示
                    resParam.setRow(i + 1);
                    resParam.setMsg(Objects.equals(lang, LanguageEnum.LANGUAGE_ZH_CN.getLang()) ?"第" + (i + 1) + "行数据有错误:" + e.getMessage():"Line " + (i + 1) + "error: " + e.getMessage());
                    resParam.setImmediately(true);
                    return resParam;
                }
            }
            if (CollectionUtils.isNotEmpty(userList)) {
                setResParam(resParam, total, userList, errorRows);
                return resParam;
            }
            resParam.setMsg(Objects.equals(lang, LanguageEnum.LANGUAGE_ZH_CN.getLang()) ? "数据错误!导入0条" : "Data error! Import 0 items");
            resParam.setImmediately(true);
            return resParam;
        } catch (Exception e) {
            resParam.setMsg(e.getMessage());
            resParam.setImmediately(true);
            return resParam;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void destroyUser(String userId) {
        // 清空注销用户的所有数据
        userMapper.delete(new LambdaQueryWrapper<User>().eq(User::getUserId, userId));
        userExtensionService.remove(new LambdaQueryWrapper<UserExtension>().eq(UserExtension::getUserId, userId));
        userCollectionService.remove(new LambdaQueryWrapper<UserCollection>().eq(UserCollection::getUserId, userId));
        userCollectionShopService.remove(new LambdaQueryWrapper<UserCollectionShop>().eq(UserCollectionShop::getUserId, userId));
        eventPublisher.publishEvent(new UserDestroyEvent(userId));
    }

    private boolean checkData(Integer lang, Set<String> phoneSet, Set<String> mailSet, List<String> errorRows, int i, String phone, String password, String nickName, String userMail) {
        // 手机号必须是11位
        if (!PrincipalUtil.isMobile(phone)) {
            errorRows.add(Objects.equals(lang, LanguageEnum.LANGUAGE_ZH_CN.getLang()) ? "第"+ (i + 1) + "行手机号格式有误"
                    : "The format of the cell phone number in line " + (i + 1) + " is wrong");
            return true;
        }
        if (StrUtil.isBlank(password)) {
            errorRows.add(Objects.equals(lang, LanguageEnum.LANGUAGE_ZH_CN.getLang()) ? "第"+ (i + 1) + "行密码为空"
                    : "Line " + (i + 1) + " password is empty");
            return true;
        }
        if (Objects.isNull(nickName) || StrUtil.isBlank(nickName)) {
            errorRows.add(Objects.equals(lang, LanguageEnum.LANGUAGE_ZH_CN.getLang()) ? "第"+ (i + 1) + "行昵称为空"
                    : "Line " + (i + 1) + " nickname is empty");
            return true;
        }
        if (nickName.length() > Constant.MAX_NICK_NAME_LENGTH) {
            errorRows.add(Objects.equals(lang, LanguageEnum.LANGUAGE_ZH_CN.getLang()) ? "第"+ (i + 1) + "行昵称长度超过15"
                    : "Line "+ (i + 1) +" nickname length exceeds 15");
            return true;
        }
        if (StrUtil.containsBlank(nickName)) {
            errorRows.add(Objects.equals(lang, LanguageEnum.LANGUAGE_ZH_CN.getLang()) ? "第"+ (i + 1) + "行昵称包含空格"
                    : "The " + (i + 1) + " line of the nickname includes spaces");
            return true;
        }
        if (StrUtil.isNotBlank(phone) && phoneSet.contains(phone)) {
            errorRows.add(Objects.equals(lang, LanguageEnum.LANGUAGE_ZH_CN.getLang()) ? "第"+ (i + 1) + "行手机号码重复"
                    : "Duplicate cell phone number in line " + (i + 1));
            return true;
        }
        if (StrUtil.isNotBlank(userMail) && mailSet.contains(userMail)) {
            errorRows.add(Objects.equals(lang, LanguageEnum.LANGUAGE_ZH_CN.getLang()) ? "第"+ (i + 1) + "行邮箱重复"
                    : "Line "+ (i + 1) +" mailbox duplicate");
            return true;
        }
        return false;
    }

    private void setResParam(UserExcelParam resParam, int total, List<UserRegisterExcelParam> userList, List<String> errorRows) {
        resParam.setTotal(total);
        resParam.setSuccessNum(userList.size());
        resParam.setErrorNum(errorRows.size());
        resParam.setErrorRowInfos(errorRows);
        resParam.setParam(Json.toJsonString(userList));
        resParam.setImmediately(false);
        resParam.setSuccess(true);
    }

    @NotNull
    private UserRegisterExcelParam getUserRegisterExcelParam(Integer lang, List<UserLevelParam> ordinary, List<UserLevelParam> pay, List<String> errorRows, int i, String serialNo, String phone, String password, String levelType, String vipEndTime, String nickName, String userMail, String sex, String birthDate, String userMemo, String score, String balance, String growth) {
        UserRegisterExcelParam param = new UserRegisterExcelParam();
        param.setSerialNo(serialNo);
        param.setPhone(phone);
        param.setNickName(nickName);
        param.setUserMail(userMail);
        param.setPassword(password);
        param.setSex(sex);
        param.setBirthDate(birthDate);
        param.setUserMemo(userMemo);
        String error = null;
        try {
            error = score;
            long scoreValue = StrUtil.isBlank(score) ? 0 : new BigDecimal(score).longValue();
            param.setScore(Math.max(scoreValue, 0));
            error = balance;
            double balanceValue = StrUtil.isBlank(balance) ? 0.00 : Arith.roundByBanker(new BigDecimal(balance).doubleValue(), 2);
            param.setBalance(balanceValue < 0 ? 0.00 : balanceValue);
            error = growth;
            int growthValue = StrUtil.isBlank(growth) ? 0 : new BigDecimal(growth).intValue();
            param.setGrowth(Math.max(growthValue, 0));
            error = levelType;
            param.setLevelType(StrUtil.isBlank(levelType) ? 0 : new BigDecimal(levelType).intValue());
        } catch (NumberFormatException e) {
            throw new YamiShopBindException(Objects.equals(lang, LanguageEnum.LANGUAGE_ZH_CN.getLang())?"输入内容[" + error + "]格式错误":"Wrong format of input" + error);
        }
        if (Objects.equals(1, param.getLevelType()) && StrUtil.isBlank(vipEndTime)) {
            errorRows.add(Objects.equals(lang, LanguageEnum.LANGUAGE_ZH_CN.getLang())?"第"+ (i + 1) + "行" + "付费会员的vip结束时间为空":"Line" + (i + 1) +"is empty for vip end time for paid members");
            return null;
        }
        if (Objects.equals(1, param.getLevelType())) {
            param.setVipEndTime(DateUtil.parse(vipEndTime, "yyyy-MM-dd"));
        }
        param.setLevel(getUserLevelByGrowthAndType(Objects.equals(0, param.getLevelType()) ? ordinary : pay, param.getGrowth()));
        return param;
    }

    private Integer getUserLevelByGrowthAndType(List<UserLevelParam> levelParams, Integer growth) {
        int level = 1;
        for (UserLevelParam levelParam : levelParams) {
            if (growth >= levelParam.getNeedGrowth()) {
                level = levelParam.getLevel();
            }
        }
        return level;
    }

    private void downloadUserModelExcel(HttpServletResponse response) {
        //通过工具类创建writer
        ExcelWriter writer = ExcelUtil.getBigWriter();
        // 商品导出or模板
        List<String> headerList = getHeadList();
        Sheet sheet = writer.getSheet();
        writer.writeRow(headerList);

        // 列表设置为文本格式
        CellStyle style = writer.createCellStyle();
        try (Workbook workbook = writer.getWorkbook()) {
            DataFormat format = workbook.createDataFormat();
            style.setDataFormat(format.getFormat("@"));

            for (int i = 0; i < headerList.size(); i++) {
                if (i == 0) {
                    sheet.setColumnWidth(i, 10 * 256);
                    sheet.setDefaultColumnStyle(i, style);
                } else if (i == 3) {
                    sheet.setColumnWidth(i, 30 * 256);
                    style.setWrapText(true);
                    sheet.setDefaultColumnStyle(i, style);
                } else if (i == 4) {
                    sheet.setColumnWidth(i, 40 * 256);
                    style.setWrapText(true);
                    sheet.setDefaultColumnStyle(i, style);
                } else if (i == 9) {
                    sheet.setColumnWidth(i, 40 * 256);
                    sheet.setDefaultColumnStyle(i, style);
                } else {
                    sheet.setColumnWidth(i, 20 * 256);
                    sheet.setDefaultColumnStyle(i, style);
                }
            }
            // 会员类型 0普通会员 1付费会员
            String[] type = {"0", "1"};
            PoiExcelUtil.createDropDownList(sheet, type, 1, 50000, 3, 3);
            // 性别选项
            String[] sexList = {"0", "1"};
            PoiExcelUtil.createDropDownList(sheet, sexList, 1, 50000, 7, 7);
            PoiExcelUtil.writeExcel(response, writer);
        } catch (Exception e) {
            log.error("下载会员导入模板错误:", e);
        }
    }


    private Double divRate(Integer a, Integer b, Integer scale) {
        if (Objects.isNull(b) || b == 0 || Objects.isNull(a)) {
            return 0.0;
        }
        return Arith.div(a, b, scale);
    }

    private Double divAverage(Double a, Double b, Integer scale) {
        if (Objects.isNull(b) || b == 0 || Objects.isNull(a)) {
            return 0.0;
        }
        return Arith.div(a, b, scale);
    }
    private List<String> getHeadList() {
        Integer lang = I18nMessage.getDbLang();
        String[] header = {"序号", "手机号(必填)", "密码(必填)", "会员类型(0普通会员/1付费会员,必填)", "vip结束时间(格式:2021-11-01，会员类型是1则必填)",
                "用户昵称(必填，最多15个字)", "邮箱", "性别(0男/1女)", "生日(格式:1989-08-08)", "备注",
                "积分(限整数)", "余额(精确小数点后两位，四舍五入)", "成长值(限整数)"};
        String[] headerEn = {"Seq", "Mobile(*)", "Password(*)", "Member Type(0 General Member/1 Paid Member,*)", "Vip End Time(Format:2021-11-01，Required if membership type is 1)",
                "NickName(Maximum 15 characters*)", "Mail", "Sex(0 Man/1 Female)", "BirthDay(Format:1989-08-08)", "Remarks",
                "Score(Limited to integers)", "Balance(Exactly two decimal places, rounded to the nearest two)", "Growth(Limited to integers)"};
        return Arrays.asList(Objects.equals(lang, LanguageEnum.LANGUAGE_ZH_CN.getLang()) ? header : headerEn);
    }
}
